home *** CD-ROM | disk | FTP | other *** search
/ The 640 MEG Shareware Studio 2 / The 640 Meg Shareware Studio CD-ROM Volume II (Data Express)(1993).ISO / clang / jcool01.zip / M_VECTOR.H < prev    next >
C/C++ Source or Header  |  1992-09-25  |  14KB  |  365 lines

  1. //
  2. // Copyright (C) 1991 Texas Instruments Incorporated.
  3. // Copyright (C) 1992 General Electric Company.
  4. //
  5. // Permission is granted to any individual or institution to use, copy, modify,
  6. // and distribute this software, provided that this complete copyright and
  7. // permission notice is maintained, intact, in all copies and supporting
  8. // documentation.
  9. //
  10. // Texas Instruments Incorporated, General Electric Company,
  11. // provides this software "as is" without express or implied warranty.
  12. //
  13. // Created: VDN 02/21/92 -- new version adapted from Matrix.h
  14. // Updated: JAM 08/15/92 -- removed DOS specifics, stdized #includes
  15. // Updated: JAM 08/24/92 -- modernized template syntax, remove macro hacks
  16. //                          non-template classes CoolM_Vector=>CoolBase_M_Vector
  17. // Updated: JAM 08/24/92 -- removed references to envelope class
  18. // Updated: JAM 08/24/92 -- made some binary member funcs friends instead
  19. // Updated: JAM 08/24/92 -- made put()'s value a 'const' Type&
  20. // Updated: JAM 09/26/92 -- put envelope back but using modern templates
  21. //
  22. // The parameterized M_Vector<Type>  class is publicly   derived from the M_Vector
  23. // class and implements one dimensional arithmetic  vectors  of a user specified
  24. // type.   This is accompilshed by using  the parameterized  type capability of
  25. // C++.  The only constraint placed on the type  is  that it must  overload the
  26. // following operators: +, -,  *,  and /. Thus, it will  be possible to have  a
  27. // M_Vector of  type Complex.  The M_Vector<Type> class  is static in size, that is
  28. // once a  M_Vector<Type> of  a particular  size has been   declared, there is no
  29. // dynamic growth or resize method available.
  30. //
  31. // Each vector contains  a protected  data section  that has a  Type* slot  that
  32. // points to the  physical memory allocated  for the one  dimensional array. In
  33. // addition, an integer  specifies   the number  of  elements  for the
  34. // vector.  These values  are provided in the  constructors. A single protected
  35. // slot  contains a pointer  to a compare  function  to   be used  in  equality
  36. // operations. The default function used is the built-in == operator.
  37. //
  38. // Four  different constructors are provided.  The  first constructor takes an
  39. // integer arguments  specifying the  length. Enough memory is
  40. // allocated to hold [length] elements  of type Type.  The second constructor
  41. // takes the  same first argument, but  also accepts  an additional second
  42. // argument that is  a reference to  an  object of  the appropriate  type whose
  43. // value is used as an initial fill value.  The third constructor is similar to
  44. // the third, except that it accpets a variable number of initialization values
  45. // for the M_Vector.  If there are  fewer values than elements,  the rest are set
  46. // to zero. Finally, the last constructor takes a single argument consisting of
  47. // a reference to a M_Vector and duplicates its size and element values.
  48. //
  49. // Methods   are  provided   for destructive   scalar   and vector  addition,
  50. // multiplication, check for equality  and inequality, fill, reduce, and access
  51. // and set individual elements.  Finally, both  the  input and output operators
  52. // are overloaded to allow for fomatted input and output of vector elements.
  53. //
  54. // M_Vector is a special type of matrix, and is implemented for space and time
  55. // efficiency. When vector is pre_multiplied by/with matrix, m*v, vector is
  56. // implicitly a column matrix. When vector is post_multiplied by/with matrix, v*m,
  57. // vector is implicitly a row matrix.
  58. //
  59.  
  60. #ifndef M_VECTORH                // If no M_Vector class,
  61. #define M_VECTORH                // define it
  62.  
  63. #ifndef STDARGH
  64. #include <stdarg.h>                // for variable arglists
  65. #define STDARGH
  66. #endif
  67.  
  68. #ifndef MATHH
  69. #include <math.h>                // for sqrt
  70. #define MATHH
  71. #endif
  72.  
  73. #ifndef BASE_M_VECTORH                // If no base class definition
  74. #include <cool/Base_M_Vector.h>            // include it
  75. #endif    
  76.  
  77. #include <cool/Matrix.h>
  78.  
  79. //## hack to workaround BC++ 3.1 Envelope bug
  80. #undef CoolEnvelope_H
  81. #define CoolEnvelope CoolEnvelope_M_Vector
  82.  
  83. template<class CoolLetter> class CoolEnvelope;
  84.  
  85. template<class Type>
  86. class CoolM_Vector : public CoolBase_M_Vector {
  87. public:
  88.   CoolM_Vector(unsigned int len=1);        // v (n);
  89.   CoolM_Vector(unsigned int len, const Type& v0); // m(n,val);
  90.   CoolM_Vector(unsigned int len, int n, Type v00, ...); // Opt. values
  91.   CoolM_Vector(const CoolM_Vector<Type>&);        // v1(v2);
  92.   ~CoolM_Vector();                    // Destructor
  93.   
  94.   inline void put (unsigned int i, const Type&);    // Assign value
  95.   inline Type& get (unsigned int i);        // Get value
  96.   void fill (const Type&);            // set elements to value
  97.   
  98.   inline Type& operator() (unsigned int i);    // Access wo checks
  99.   
  100.   CoolM_Vector<Type>& operator= (const Type&);    // Assignment: m = 2;
  101.   CoolM_Vector<Type>& operator= (const CoolM_Vector<Type>&); // Assignment: m = n;
  102.   inline CoolM_Vector<Type>& operator= (CoolEnvelope< CoolM_Vector<Type> >&); // envelope to vector
  103.   
  104.   Boolean operator== (const CoolM_Vector<Type>&) const; // CoolM_Vector equality test
  105.   inline Boolean operator!= (const CoolM_Vector<Type>&) const; // inequality test
  106.   void set_compare (Boolean (*) (const Type&, const Type&) = NULL);       // Compare function
  107.   
  108.   friend ostream& operator<< (ostream&, const CoolM_Vector<Type>&);
  109.   /*inline##*/ friend ostream& operator<< (ostream&, const CoolM_Vector<Type>*);
  110.   
  111.   CoolM_Vector<Type>& operator+= (const Type&);    // binary operation and assignment
  112.   CoolM_Vector<Type>& operator*= (const Type&);    // Mutate vector data
  113.   CoolM_Vector<Type>& operator/= (const Type&);
  114.   inline CoolM_Vector<Type>& operator-= (const Type&);    
  115.   
  116.   CoolM_Vector<Type>& operator+= (const CoolM_Vector<Type>&);
  117.   CoolM_Vector<Type>& operator-= (const CoolM_Vector<Type>&); 
  118.  
  119.   CoolM_Vector<Type>& pre_multiply (const CoolMatrix<Type>&); // v = m * v
  120.   CoolM_Vector<Type>& post_multiply (const CoolMatrix<Type>&); // v = v * m
  121.   inline CoolM_Vector<Type>& operator*= (const CoolMatrix<Type>&); // v = v * m, post-multiply
  122.  
  123.   CoolEnvelope< CoolM_Vector<Type> > operator- () const;        // negation and 
  124.   CoolEnvelope< CoolM_Vector<Type> > operator+ (const Type&) const;    // all binary operations 
  125.   CoolEnvelope< CoolM_Vector<Type> > operator* (const Type&) const;    // return by values.
  126.   CoolEnvelope< CoolM_Vector<Type> > operator/ (const Type&) const;
  127.   
  128.   inline CoolEnvelope< CoolM_Vector<Type> > operator- (const Type&) const; 
  129.   /*inline##*/ friend CoolEnvelope< CoolM_Vector<Type> > operator+(const Type&, const CoolM_Vector<Type>&);
  130.   /*inline##*/ friend CoolEnvelope< CoolM_Vector<Type> > operator-(const Type&, const CoolM_Vector<Type>&);
  131.   /*inline##*/ friend CoolEnvelope< CoolM_Vector<Type> > operator*(const Type&, const CoolM_Vector<Type>&);
  132.  
  133. // Fewer unnecessary copying with CoolEnvelope
  134. //   friend CoolM_Vector<Type> operator+ (const CoolM_Vector<Type>&,
  135. //                     const CoolM_Vector<Type>&);
  136. //   friend CoolM_Vector<Type> operator- (const CoolM_Vector<Type>&,
  137. //                     const CoolM_Vector<Type>&);
  138.  
  139.   friend CoolEnvelope< CoolM_Vector<Type> > operator* (const CoolM_Vector<Type>&, const CoolMatrix<Type>&);
  140.   friend CoolEnvelope< CoolM_Vector<Type> > operator* (const CoolMatrix<Type>&, const CoolM_Vector<Type>&);
  141.  
  142.   CoolEnvelope< CoolM_Vector<Type> > abs() const;            // r[i] = abs(v[i])
  143.   CoolEnvelope< CoolM_Vector<Type> > sign() const;            // r[i] = sign(v[i])
  144.   CoolEnvelope< CoolM_Vector<Type> > extract (unsigned int len, unsigned int start=0) const; // subvector
  145.   CoolM_Vector<Type>& update (const CoolM_Vector<Type>&, unsigned int start=0);
  146.   
  147.   friend CoolEnvelope< CoolM_Vector<Type> > element_product (const CoolM_Vector<Type>&, // v[i] = a[i]*b[i]
  148.                     const CoolM_Vector<Type>&);
  149.   friend CoolEnvelope< CoolM_Vector<Type> > element_quotient (const CoolM_Vector<Type>&, // v[i] = a[i]/b[i]
  150.                            const CoolM_Vector<Type>&);
  151.  
  152.   inline Type squared_magnitude() const;    // dot(v,v)
  153.   inline Type magnitude() const;        // sqrt(dot(v,v))
  154.   inline CoolM_Vector<Type>& normalize();    // v /= sqrt(dot(v,v))
  155.   
  156.   inline Type& x() const;            // get coordinates along
  157.   inline Type& y() const;            // 4 axes.
  158.   inline Type& z() const;            
  159.   inline Type& t() const;            
  160.  
  161.   friend Type dot_product (const CoolM_Vector<Type>&, // dot-product of n-dim vectors
  162.                const CoolM_Vector<Type>&); 
  163.   friend Type cross_2d (const CoolM_Vector<Type>&,    // cross-product of 2d-vectors
  164.             const CoolM_Vector<Type>&);
  165.   friend CoolEnvelope< CoolM_Vector<Type> > cross_3d (const CoolM_Vector<Type>&, // cross-product 
  166.                        const CoolM_Vector<Type>&); // of 3d-vectors 
  167.  
  168. protected:
  169.   Type* data;                    // Pointer to the CoolM_Vector 
  170.   static Boolean (*compare_s) (const Type&, const Type&);    // Pointer operator== function
  171.   friend Boolean CoolM_Vector_is_data_equal (const Type&, const Type&);
  172. };
  173.  
  174. //## BC++ 3.1 bug
  175. void hack(CoolM_Vector<int>);
  176. void hack(CoolM_Vector<float>);
  177. void hack(CoolM_Vector<double>);
  178. //## add your type above
  179. #include <cool/Envelope.h>    //## BC++ 3.1 bug prevents from moving to top
  180.  
  181. // Use envelope to avoid deep copy on return by value, and mutate in place
  182. template<class Type>
  183. inline CoolEnvelope< CoolM_Vector<Type> > operator+ (const CoolM_Vector<Type>&arg1,const CoolM_Vector<Type>&arg2)
  184.    { return CoolEnvOp(add)(arg1, arg2); }
  185. template<class Type>
  186. inline CoolEnvelope< CoolM_Vector<Type> > operator- (const CoolM_Vector<Type>&arg1,const CoolM_Vector<Type>&arg2)
  187.    { return CoolEnvOp(minus)(arg1, arg2); }
  188.  
  189.  
  190. // get -- Get the element at specified index and return value
  191. // Input: *this, index
  192. // Output: Element value
  193.  
  194. template<class Type> 
  195. inline Type& CoolM_Vector<Type>::get (unsigned int index) {
  196. #if ERROR_CHECKING
  197.   if (index >= this->num_elmts)            // If invalid index specified
  198.     this->index_error ("get", #Type, index);    // Raise exception
  199. #endif
  200.   return this->data[index];
  201. }
  202.  
  203. // put -- Put the element value at specified index
  204. // Input: *this, index, value
  205. // Output: Element value
  206.  
  207. template<class Type> 
  208. inline void CoolM_Vector<Type>::put (unsigned int index, const Type& value) {
  209. #if ERROR_CHECKING
  210.   if (index >= this->num_elmts)            // If invalid index specified
  211.     this->index_error ("put", #Type, index);    // Raise exception
  212. #endif
  213.   this->data[index] = value;            // Assign data value
  214. }
  215.  
  216. // operator() -- Overload () to get the element at specified index and return value
  217. // Input: *this, index
  218. // Output: Element reference
  219.  
  220. template<class Type> 
  221. inline Type& CoolM_Vector<Type>::operator() (unsigned int index) {
  222.   return this->data[index];            // fast access without checks.
  223. }
  224.  
  225. // operator=  -- Assignment from an envelope back to real vector
  226. // Input:     envelope reference
  227. // Output:    vector reference with contents in envelope being swapped over
  228.  
  229. template<class Type>
  230. inline CoolM_Vector<Type>& CoolM_Vector<Type>::operator= (CoolEnvelope< CoolM_Vector<Type> >& env){
  231.   env.shallow_swap((CoolEnvelope< CoolM_Vector<Type> >*)this, &env); // same physical layout
  232.   return *this;
  233. }
  234.  
  235. // operator-= -- Destructive vector subtraction of a scalar.
  236. // Input:        *this, scalar value
  237. // Output:       New vector reference
  238.  
  239. template<class Type> 
  240. inline CoolM_Vector<Type>& CoolM_Vector<Type>::operator-= (const Type& value) {
  241.   return *this += (- value);
  242. }
  243.  
  244.  
  245. // operator*= -- Destructive multiply vector with matrix, and assignment. v = v*m
  246. //               num_elmts of vector must match num_rows of matrix 
  247. // Input:        *this, matrix reference
  248. // Output:       Updated *this vector reference
  249.  
  250. template<class Type>
  251. inline CoolM_Vector<Type>& CoolM_Vector<Type>::operator*= (const CoolMatrix<Type>& m) {
  252.   return this->post_multiply(m);
  253. }
  254.  
  255.  
  256. // operator<< -- Overload the output operator to print a CoolM_Vector
  257. // Input:        ostream reference, CoolM_Vector pointer
  258. // Output:       ostream reference
  259.  
  260. template<class Type> 
  261. inline ostream& operator<< (ostream& os, const CoolM_Vector<Type>* m) {
  262.    return os << *m;
  263. }
  264.  
  265. // operator!= -- Perform not equal comparison test
  266. // Input:        *this, vector reference
  267. // Output:       TRUE/FALSE
  268.  
  269. template<class Type> 
  270. inline Boolean CoolM_Vector<Type>::operator!= (const CoolM_Vector<Type>& v) const {
  271.   return (!operator== (v));
  272. }
  273.  
  274.  
  275. template<class Type> 
  276. inline CoolEnvelope< CoolM_Vector<Type> > operator+ (const Type& value,
  277.                       const CoolM_Vector<Type>& v) {
  278.   return v + value;
  279. }
  280.  
  281. // operator- -- Non-destructive vector substraction of a scalar.
  282. // Input:       *this, scalar value
  283. // Output:      New vector 
  284.  
  285. template<class Type> 
  286. inline CoolEnvelope< CoolM_Vector<Type> > CoolM_Vector<Type>::operator-(const Type& value) const {
  287.   return (*this) + (- value);
  288. }
  289.  
  290. template<class Type> 
  291. inline CoolEnvelope< CoolM_Vector<Type> > operator- (const Type& value,
  292.                       const CoolM_Vector<Type>& v) {
  293.   return (- v) + value;
  294. }
  295.  
  296.  
  297. template<class Type> 
  298. inline CoolEnvelope< CoolM_Vector<Type> > operator* (const Type& value,
  299.                       const CoolM_Vector<Type>& v) {
  300.   return v * value;
  301. }
  302.  
  303.  
  304. // squared_magnitude -- Return dot-product(*this,*this)
  305. // Input:    *this
  306. // Ouput:    squared of magnitude or dot-product(v,v).
  307.  
  308. template<class Type>
  309. inline Type CoolM_Vector<Type>::squared_magnitude() const {
  310.   return dot_product(*this,*this);
  311. }
  312.  
  313. // magnitude -- Return square-root of dot-product(*this,*this)
  314. // Input:    *this
  315. // Ouput:    magnitude of vector.
  316.  
  317. template<class Type>
  318. inline Type CoolM_Vector<Type>::magnitude() const {
  319.   return (Type) sqrt(double(dot_product(*this,*this)));
  320. }
  321.  
  322. // normalize -- Mutate vector to have magnitude = 1.
  323. // Input:    *this
  324. // Ouput:    Mutated vector
  325.  
  326. template<class Type>
  327. inline CoolM_Vector<Type>& CoolM_Vector<Type>::normalize() {
  328.   Type mag = this->magnitude();
  329.   return (*this /= mag);
  330. }
  331.  
  332.  
  333. // x,y,z,t -- return the coordinates along the axes
  334. // Input:     *this
  335. // Output:    coordinate by reference
  336.  
  337. template<class Type>                
  338. inline Type& CoolM_Vector<Type>::x() const{    
  339.   return data[0];
  340. }        
  341.  
  342. template<class Type>
  343. inline Type& CoolM_Vector<Type>::y() const {
  344.   return data[1];
  345. }
  346.  
  347. template<class Type>
  348. inline Type& CoolM_Vector<Type>::z() const {
  349.   return data[2];
  350. }        
  351.  
  352. template<class Type>
  353. inline Type& CoolM_Vector<Type>::t() const {
  354.   return data[3];
  355. }
  356.  
  357. //## hack to workaround BC++ 3.1 Envelope bug
  358. #undef CoolEnvelope
  359.  
  360. #endif                        // End of M_VECTORH
  361.  
  362.  
  363.  
  364.  
  365.